#include <linux/module.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>

#define CHR_DEV_NAME "chr_dev"
static int chr_major;
static int chr_cls;

static int chr_open(struct inode *inode, struct file *file)
{

	printk("[DRV-OPEN] open file ok!\n");

	return 0;
}

static ssize_t chr_read(struct file *file, char *user, size_t size,loff_t *loff)
{
	int rbuf[32];

	copy_from_user(rbuf,user, size);

	printk("buf: %d\n", rbuf[0]);

	return 0;
}

static ssize_t chr_write(struct file *file, const char *user, size_t size, loff_t *loff)
{

	int rbuf[32];

	copy_from_user(rbuf,user, size);

	printk("buf: %d\n", rbuf[0]);
	return 0;
}

static int chr_release(struct inode *inode, struct file *file)
{

	return 0;
}

static struct file_operations chr_ops ={
	.owner = THIS_MODULE,
	.open = chr_open,
	.write = chr_write,
	.read  = chr_read,
	.release = chr_release,
};


static int chr_probe(struct platform_device * pdev)
{
	printk("[LED_DRV]  led_probe\n");

	struct resource		*res;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	
	#if 1
	printk("res.start = %ld\n", res->start);
	printk("res.end = %ld\n", res->end);
	printk("res.flags = %ld\n", res->flags);
	#endif
	
#define	AUTO_MAJOR

#ifdef AUTO_MAJOR
#define major 0
#else
#define major 123
#endif
	chr_major = register_chrdev(0, CHR_DEV_NAME, &chr_ops);
	chr_cls = class_create(THIS_MODULE, CHR_DEV_NAME);
	device_create(chr_cls, NULL, MKDEV(chr_major, 0), NULL, "chr_dev");
	
	return 0;
}

static int  chr_remove(struct platform_device *pdev)
{
	printk("[LED_DRV]  led_remove\n");

	device_destroy(chr_cls, MKDEV(chr_major, 0));
	class_destroy(chr_cls);
	unregister_chrdev(chr_major, "chr_dev");

	return 0;
}
static void chr_shutdown(struct platform_device *pdev)
{
	printk("[LED_DRV]  led_shutdown\n");
	return ;
}
static int chr_suspend(struct platform_device *pdev, pm_message_t state)
{
	printk("[LED_DRV]  led_suspend\n");
	return 0;
}
static int chr_resume(struct platform_device *pdev)
{
	printk("[LED_DRV]  led_resume\n");
	return 0;
}

static struct platform_driver led_drv = {
	.probe = chr_probe,
	.remove  =  chr_remove,
	.shutdown = chr_shutdown,
	.suspend = chr_suspend,
	.resume = chr_resume,
	.driver = {
		.name = "led",
	},
	
	//static const struct platform_device_id *id_table;
};

static int led_drv_init(void)
{
	platform_driver_register(&led_drv );
	return 0;
}

static void led_drv_exit(void)
{
	platform_driver_unregister(&led_drv );
	return ;
}

module_init(led_drv_init);
module_exit(led_drv_exit);

MODULE_LICENSE("GPL");




